package rolesystem.agentlogic.GUI;

import java.awt.*;
import java.util.ArrayList;
import java.util.concurrent.Semaphore;

import rolesystem.agentlogic.managers.EnvironmentManager;
import rolesystem.agentlogic.managers.KnownEnvironmentManager;
import rolesystem.agentlogic.utilityclasses.AgentData;
import rolesystem.agentlogic.utilityclasses.AgentMap;
import rolesystem.agentlogic.utilityclasses.PositionSq;
import rolesystem.agentlogic.utilityclasses.Square;

public class EnvVisualizer extends Canvas
{
	/**
	 * 
	 */
	private static final long serialVersionUID = 3111297938794921923L;
	private static Image offScreenImage;
	private Graphics offScreenGraphics;
	private static Image offScreenImageDrawed;
	
	private Graphics offScreenGraphicsDrawed;
	
	private static int cellSize;
	private static Dimension dim;
	private static ArrayList<Square>[][] env;
	
	
	private static Semaphore semaphore;
	private static Semaphore semaphoreUp;
	
	
	static
	{	
		EnvVisualizer.semaphore = new Semaphore(1);
		EnvVisualizer.semaphoreUp = new Semaphore(1); 
	}
	
	public EnvVisualizer( int cellSize_p, int dim_x,int dim_y) 
	{
		cellSize = cellSize_p;
		
		setBackground(new Color(0x999999));
		dim = new Dimension( dim_x, dim_y);	    
	}
	
	
	public static void updateObj(ArrayList<Square>[][] env_p) 
	{
		env=env_p;
	}
	
	public static void updateAgent(AgentData updatedAgent) 
	{
		semaphore.acquireUninterruptibly();
		
		AgentMap.updateAgent(updatedAgent);
		
		semaphore.release();
	}
	
	/** 
	 * Use double buffering.
	 * @see java.awt.Component#update(java.awt.Graphics)
	 */
	public void update(Graphics g) 
	{
		semaphoreUp.acquireUninterruptibly();
		
		Dimension d = getSize();
		
		if ((offScreenImage == null)) 
		{
			offScreenImage = createImage(d.width, d.height);
			offScreenGraphics = offScreenImage.getGraphics();
		}
		
		paint(offScreenGraphics);
		g.drawImage(offScreenImage, 0, 0, null);
		
		semaphoreUp.release();
	}
	
	public void paint(Graphics g) 
	{
		semaphore.acquireUninterruptibly();  
		
		// Draw grid on background image, which is faster
		if (offScreenImageDrawed == null) 
		{
			Dimension d = getSize();
			
			offScreenImageDrawed = createImage(d.width, d.height);
			offScreenGraphicsDrawed = offScreenImageDrawed.getGraphics();
			
			// draw background
			offScreenGraphicsDrawed.setColor(getBackground());
			offScreenGraphicsDrawed.fillRect(0, 0, d.width, d.height);
			offScreenGraphicsDrawed.setColor(Color.gray);
			offScreenGraphicsDrawed.fillRect(0, 0, cellSize * dim.width - 1, cellSize * dim.height - 1);
			offScreenGraphicsDrawed.setColor(getBackground());
			
			for (int x = 1; x < dim.width; x++) 
			{
				offScreenGraphicsDrawed.drawLine(x * cellSize - 1, 0, x * cellSize - 1, cellSize * dim.height - 1);
			}
			for (int y = 1; y < dim.height; y++) 
			{
				offScreenGraphicsDrawed.drawLine( 0, y * cellSize - 1, cellSize * dim.width - 1, y * cellSize - 1);
			}
			
		}
		g.drawImage(offScreenImageDrawed, 0, 0, null);
		
		// draw obstacles
		g.setColor(Color.green);
		
		for(int i=0;i< EnvironmentManager.ENV_MAX_X; i++)
		{
			for(int j=0;j< EnvironmentManager.ENV_MAX_Y; j++)
			{
				if(env[i][j].get(0).getBlocked()==true)
				{   
					g.fillRect(i * cellSize, j * cellSize, cellSize - 1, cellSize - 1); 
				}
			}    
		}
		
		// Draw Nest
		g.setColor(Color.red);
		g.fillRect(1 * cellSize, 1 * cellSize, cellSize - 1, cellSize - 1);
		
		
		//Draw Agents
		g.setColor(Color.black);
		
		for(int i=0;i<AgentMap.getSize();i++)
		{
			g.setColor(Color.black);
			g.fillRect(AgentMap.getPositionByIndex(i).pos_x  * cellSize, AgentMap.getPositionByIndex(i).pos_y * cellSize, cellSize - 1, cellSize - 1); 
			
			g.setFont(new Font("SanSerif", Font.PLAIN, 13));
			g.setColor(Color.red);
			FontMetrics fm = g.getFontMetrics();
			int w = fm.stringWidth(String.valueOf(AgentMap.getIdByIndex(i)));
			int h = fm.getAscent();
			g.drawString(String.valueOf(AgentMap.getIdByIndex(i)), (AgentMap.getPositionByIndex(i).pos_x  * cellSize)+(w*2/3), (AgentMap.getPositionByIndex(i).pos_y  * cellSize)+ h*(4/3) );
		}  
		
		g.setColor(Color.blue);
		
		for(int i=0;i< EnvironmentManager.ENV_MAX_X; i++)
		{
			for(int j=0;j< EnvironmentManager.ENV_MAX_Y; j++)
			{
				if(KnownEnvironmentManager.getMergedKnownPosition(new PositionSq(i,j)).getKnown()==true)
				{   
					g.fillRect(i * cellSize, j * cellSize, cellSize - 1, cellSize - 1); 
				}
			}    
		}
		
		semaphore.release();
		
	}
	
}
